﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Reflection;

namespace ST.Buz.Base
{
	public partial class BuzContext : DbContext
	{
		protected readonly ILogger logger;

		public BuzContext(DbContextOptions<BuzContext> options, ILogger<BuzContext> _logger)
		: base(options)
		{
			logger = _logger;
			//Database.EnsureCreated();
			//Database.Migrate();
		}

		/// <summary>
		/// 需要一个不是泛型的构造函数，否则使用依赖注入会出问题
		/// </summary>
		/// <param name="options"></param>
		protected BuzContext(DbContextOptions options)
			: base(options)
		{
		}

		protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
		{
			//if (!optionsBuilder.IsConfigured)
			//{
			//	optionsBuilder.UseSqlServer(@"Server=(local);Database=SYJCY;Integrated Security=True;Trusted_Connection=True;", b => b.MigrationsAssembly("ST.Sys.DAL.Sql2008"));
			//}
		}

		protected override void OnModelCreating(ModelBuilder modelBuilder)
		{
#if DEBUG
			try
			{
				#region 系统相关
				OnModelCreatingSys(modelBuilder);
				#endregion

				#region 业务相关
				OnModelCreatingBuz(modelBuilder);
				#endregion

				base.OnModelCreating(modelBuilder);
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "同步表结构出错");
			}
#endif
		}

		#region 其他辅助方法
		public List<T> ExecuteReader<T>(string sql, DbParameter[] parameters, CommandType cmdType = CommandType.StoredProcedure) where T : new()
		{
			List<T> lst = new List<T>();
			using (var cmd = Database.GetDbConnection().CreateCommand())
			{
				cmd.CommandText = sql;
				cmd.CommandType = cmdType;
				if (parameters != null && parameters.Length > 0)
				{
					cmd.Parameters.AddRange(parameters);
				}
				Database.OpenConnection();
				using (DbDataReader dr = cmd.ExecuteReader())
				{
					var columns = dr.GetColumnSchema();
					List<string> lstColumn = new List<string>();
					foreach (var col in columns)
					{
						lstColumn.Add(col.ColumnName);
					}
					while (dr.Read())
					{
						T m = new T();
						PropertyInfo[] properties = m.GetType().GetProperties();
						foreach (PropertyInfo pi in properties)
						{
							if (pi.CanWrite && lstColumn.Contains(pi.Name))
							{
								// 判断此属性是否有Setter
								object value = dr[pi.Name];
								if (value != DBNull.Value)
									pi.SetValue(m, value, null);
							}
						}
						lst.Add(m);
					}
				}
				Database.CloseConnection();
			}
			return lst;
		}


		#endregion
	}
}
